<!--
  多图上传组件
  @author: haoxr
  @date 2022/11/20
  @link https://element-plus.gitee.io/zh-CN/component/upload.html
-->

<template>
  <el-upload
    v-model:file-list="fileList"
    list-type="picture-card"
    :before-upload="beforeUpload"
    :http-request="handleUpload"
    :on-remove="handleRemove"
    :on-preview="handlePreview"
    :limit="props.limit"
  >
    <el-icon><Plus /></el-icon>
  </el-upload>

  <el-dialog v-model="dialogVisible">
    <img w-full :src="dialogImageUrl" alt="Preview Image" />
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import { Plus } from "@element-plus/icons-vue";
import {
  ElMessage,
  ElUpload,
  UploadRawFile,
  UploadRequestOptions,
  UploadUserFile,
  UploadFile,
  UploadProps
} from "element-plus";
import axios from "axios";
import feedback from "@/utils/feedback";
import { checkType, uploadApi } from "./util";
import { staticUrl } from "@/utils/file";
const emit = defineEmits(["update:modelValue"]);
const props = defineProps({
  /**
   * 文件路径集合
   */
  modelValue: {
    type: Array<string>,
    default: [] as Array<string>
  },
  /**
   * 文件上传数量限制
   */
  limit: {
    type: Number,
    default: 5
  },
  /**
   * 上传类型
   * 0: 图片
   * 1:视频
   * 2:其他
   */
  fileType: {
    type: Number,
    default: 0
  }
});

const dialogImageUrl = ref("");
const dialogVisible = ref(false);

const fileList = ref([] as UploadUserFile[]);
watch(
  () => props.modelValue,
  (newVal: string[]) => {
    console.log("newVal", newVal);
    const filePaths = fileList.value.map(file => file.url);
    // 监听modelValue文件集合值未变化时，跳过赋值
    if (
      filePaths.length > 0 &&
      filePaths.length === newVal.length &&
      filePaths.every(x => newVal.some(y => y === x)) &&
      newVal.every(y => filePaths.some(x => x === y))
    ) {
      return;
    }

    if (newVal) {
      fileList.value = newVal.map(filePath => {
        return { url: filePath } as UploadUserFile;
      });
    }
  },
  { immediate: true }
);

/**
 * 自定义图片上传
 *
 * @param params
 */
async function handleUpload(options: UploadRequestOptions): Promise<any> {
  const data = await uploadApi(options.file);

  // 上传成功需手动替换文件路径为远程URL，否则图片地址为预览地址 blob:http://
  const fileIndex = fileList.value.findIndex(
    file => file.uid == (options.file as any).uid
  );

  fileList.value.splice(fileIndex, 1, {
    name: options.filename,
    url: staticUrl + data
  } as UploadUserFile);

  emit(
    "update:modelValue",
    fileList.value.map(file => file.url)
  );
}

/**
 * 删除图片
 */
function handleRemove(removeFile: UploadFile) {
  const filePath = removeFile.url;

  if (filePath) {
    // deleteFileApi(filePath).then(() => {
    //   emit(
    //     "update:modelValue",
    //     fileList.value.map(file => file.url)
    //   );
    // });
  }
}

//上传之前校验方法
const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
  let checkRes = checkType(props.fileType, rawFile.name);
  if (checkRes) {
    if (rawFile.size / 1024 / 1024 > 10) {
      feedback.msgWarning("只能上传10M以内文件!");
      return false;
    }
    return true;
  } else {
    feedback.msgWarning("不支持的文件类型!");
    return false;
  }
};

/**
 * 图片预览
 */
const handlePreview: UploadProps["onPreview"] = uploadFile => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};
</script>
